package com.mg.axechen.webview;

import com.tencent.smtt.sdk.WebSettings;

/**
 * WebView的WebSettings属性和自定义属性。
 * 1、WebSettings属性，可以让调用者自己定义WebSettings属性，从而不需要去修改BaseWebView。
 * 2、自定义属性，实现其他功能的自定属性。
 *
 * @author AxeChen
 */
public class BaseWebViewConfig {

    /**
     * 是否允许在WebView中访问内容URL（Content Url），默认允许。
     * 内容Url访问允许WebView从安装在系统中的内容提供者载入内容。
     */
    public boolean allowContentAccess = true;


    /**
     * 是否允许访问文件，默认允许。注意，这里只是允许或禁止对文件系统的访问，Assets 和 resources
     * 文件使用file:///android_asset和file:///android_res仍是可访问的。
     */
    public boolean allowFileAccess = true;

    /**
     * 是否允许运行在一个URL环境（the context of a file scheme URL）中的JavaScript访问来自其他URL环境的内容，为了保证安全，应该不允许。也请注意，这项设置只影响对file schema 资源的JavaScript访问，其他形式的访问，
     * 例如来自图片HTML单元的访问不受影响。为了防止相同的域策略（same domain policy）对ICE_CREAM_SANDWICH以及更老机型的侵害，应该显式地设置此值为false。
     */
    public boolean allowFileAccessFromFileURLs = false;

    /**
     * 是否允许运行在一个file schema URL环境下的JavaScript访问来自其他任何来源的内容，
     * 包括其他file schema URLs. 参见setAllowFileAccessFromFileURLs(boolean)，
     * 为了确保安全，应该设置为不允许，注意这项设置只影响对file schema 资源的JavaScript访问，
     * 其他形式的访问，例如来自图片HTML单元的访问不受影响。为了防止相同的域策略（same domain policy）
     * 对ICE_CREAM_SANDWICH以及更老机型的侵害，
     * 应该显式地设置此值为false。ICE_CREAM_SANDWICH_MR1 以及更老的版本此默认值为true，
     * JELLY_BEAN以及更新版本此默认值为false
     */
    public boolean allowUniversalAccessFromFileURLs = false;

    /**
     * 应用缓存API是否可用，默认值false, 结合setAppCachePath(String)使用。
     */
    public boolean appCacheEnabled = false;

    /**
     * 设置应用缓存文件的路径。为了让应用缓存API可用，
     * 此方法必须传入一个应用可写的路径。该方法只会执行一次，重复调用会被忽略。
     */
    public String appCachePath = "";


    /**
     * 是否禁止从网络下载数据，如果app有INTERNET权限，默认值为false，否则默认为true。
     * 使用setBlockNetworkImage(boolean) 只会禁止图片资源的加载。注意此值由true变为false，
     * 当前WebView展示的内容所引用的网络资源不会自动加载，直到调用了重载。如果APP没有INTERNET权限，设置此值为false会抛出SecurityException。
     */
    public boolean blockNetworkImage = true;

    /**
     * 是否使用内置的缩放机制。内置的缩放机制包括屏幕上的缩放控件（浮于WebView内容之上）和缩放手势的运用。
     * 通过setDisplayZoomControls(boolean)可以控制是否显示这些控件，默认值为false。
     */
    public boolean builtInZoomControls = false;

    /**
     * 重写使用缓存的方式，默认值LOAD_DEFAULT。缓存的使用方式基于导航类型，正常的页面加载，检测缓存，需要时缓存内容复现。
     * 导航返回时，内容不会复现，只有内容会从缓存盘中恢复。该方法允许客户端通过指定LOAD_DEFAULT, LOAD_CACHE_ELSE_NETWORK,
     * LOAD_NO_CACHE or LOAD_CACHE_ONLY的其中一项来重写其行为。
     */
    public int cacheMode = WebSettings.LOAD_DEFAULT;

    /**
     * 设置WebView字体库字体，默认“cursive”
     */
    public String cursiveFontFamily = "cursive";

    /**
     * 数据库存储API是否可用，默认值false。如何正确设置数据存储API参见setDatabasePath(String)。
     * 该设置对同一进程中的所有WebView实例均有效。
     * 注意，只能在当前进程的任意WebView加载页面之前修改此项，因为此节点之后WebView的实现类可能会忽略该项设置的改变。
     */
    public boolean databaseEnabled = false;

    /**
     * 设置默认固定的字体大小，默认为16，可取值1到72
     */
    public int defaultFixedFontSize = 16;

    /**
     * 设置默认的字体大小，默认16，可取值1到72
     */
    public int defaultFontSize = 16;

    /**
     * 设置默认的字符编码集，默认”UTF-8”
     */
    public String defaultTextEncodingName = "UTF-8";

    /**
     * 使用内置的缩放机制时是否展示缩放控件，默认值true。参见setBuiltInZoomControls(boolean).
     */
    public boolean displayZoomControls = true;

    /**
     * DOM存储API是否可用，默认false。
     */
    public boolean domStorageEnabled = false;

    /**
     * 设置fantasy字体集（font family）的名字默认为“fantasy”
     */
    public String fantasyFontFamily = "fantasy";

    /**
     * 设置固定的字体集的名字，默认为”monospace”。
     */
    public String fixedFontFamily = "monospace";

    /**
     * 定位数据库的保存路径，为了确保定位权限和缓存位置的持久化，该方法应该传入一个应用可写的路径。
     */
    public String geolocationDatabasePath = "";

    /**
     * 定位是否可用，默认为true。请注意，为了确保定位API在WebView的页面中可用，必须遵守如下约定:
     * (1) app必须有定位的权限，参见ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION；
     * (2) app必须提供onGeolocationPermissionsShowPrompt(String, GeolocationPermissions.Callback)回调方法的实现，
     * 在页面通过JavaScript定位API请求定位时接收通知。
     * 作为可选项，可以在数据库中存储历史位置和Web初始权限，参见setGeolocationDatabasePath(String).
     */
    public boolean geolocationEnabled = true;

    /**
     * 让JavaScript自动打开窗口，默认false。适用于JavaScript方法window.open()。
     */
    public boolean javaScriptCanOpenWindowsAutomatically = false;

    /**
     * 设置WebView是否允许执行JavaScript脚本，默认false，不允许
     */
    public boolean javaScriptEnabled = false;

    /**
     * 设置布局，会引起WebView的重新布局（relayout）,默认值NARROW_COLUMNS
     */
    public WebSettings.LayoutAlgorithm layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS;

    /**
     * 是否允许WebView度超出以概览的方式载入页面，默认false。即缩小内容以适应屏幕宽度。
     * 该项设置在内容宽度超出WebView控件的宽度时生效，例如当getUseWideViewPort() 返回true时。
     */
    public boolean loadWithOverviewMode = false;

    /**
     * WebView是否下载图片资源，默认为true。注意，该方法控制所有图片的下载，
     * 包括使用URI嵌入的图片（使用setBlockNetworkImage(boolean) 只控制使用网络URI的图片的下载）。
     * 如果该设置项的值由false变为true，WebView展示的内容所引用的所有的图片资源将自动下载。
     */
    public boolean loadsImagesAutomatically = true;

    /**
     * WebView是否需要用户的手势进行媒体播放，默认值为true。
     */
    public boolean mediaPlaybackRequiresUserGesture = true;

    /**
     * 设置最小的字号，默认为8
     */
    public int minimumFontSize = 8;

    /**
     * 设置最小的本地字号，默认为8。
     */
    public int minimumLogicalFontSize = 8;

    /**
     * 当一个安全的来源（origin）试图从一个不安全的来源加载资源时配置WebView的行为。默认情况下，KITKAT及更低版本默认值为MIXED_CONTENT_ALWAYS_ALLOW，
     * LOLLIPOP版本默认值MIXED_CONTENT_NEVER_ALLOW，WebView首选的最安全的操作模式为MIXED_CONTENT_NEVER_ALLOW ，
     * 不鼓励使用MIXED_CONTENT_ALWAYS_ALLOW。
     */
    public int mixedContentMode = android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW;

    /**
     * 调用requestFocus(int, Android.graphics.Rect)时是否需要设置节点获取焦点，默认值为true。
     */
    public boolean needInitialFocus = true;

    /**
     * 当WebView切换到后台但仍然与窗口关联时是否raster tiles，打开它可以避免在WebView从后台切换到前台时重新绘制，默认值false。
     * 在这种模式下后台的WebView占用更多的内存。请按如下准则显示内存的使用：
     * <p>
     * WebView的尺寸不能比设备的屏幕尺寸更大；
     * 限制在少数WebView上使用该模式；
     * 在可见的WebView和即将显现的WebView上使用；
     */
    public boolean offscreenPreRaster = false;

    /**
     * 设置无衬线字体集（sans-serif font family）的名字。默认值”sans-serif”.
     */
    public String sansSerifFontFamily = "sans-serif";

    /**
     * WebView是否保存表单数据，默认值true。
     */
    public boolean saveFormData = true;

    /**
     * 设置衬线字体集（serif font family）的名字，默认“sans-serif”。
     */
    public String serifFontFamily = "sans-serif";

    /**
     * 设置标准字体集的名字，默认值“sans-serif”。
     */
    public String standardFontFamily = "sans-seri";

    /**
     * 设置WebView是否支持多窗口。如果设置为true，
     * 主程序要实现onCreateWindow(WebView, boolean, boolean, Message)，默认false。
     */
    public boolean supportMultipleWindows = false;

    /**
     * WebView是否支持使用屏幕上的缩放控件和手势进行缩放，默认值true。设置setBuiltInZoomControls(boolean)可以使用特殊的缩放机制。
     * 该项设置不会影响zoomIn() and zoomOut()的缩放操作。
     */
    public boolean supportZoom = true;

    /**
     * 设置页面上的文本缩放百分比，默认100。
     */
    public int textZoom = 100;

    /**
     * WebView是否支持HTML的“viewport”标签或者使用wide viewport。设置值为true时，布局的宽度总是与WebView控件上的设备无关像素（device-dependent pixels）宽度一致。
     * 当值为true且页面包含viewport标记，将使用标签指定的宽度。如果页面不包含标签或者标签没有提供宽度，那就使用wide viewport。
     */
    public boolean useWideViewPort = true;

    /**
     * 设置WebView的用户代理字符串。如果字符串为null或者empty，将使用系统默认值。注意从KITKAT版本开始，加载网页时改变用户代理会让WebView再次初始化加载。
     */
    public String userAgentString = "";


    /**
     * 使用构造者模式去构造属性
     */
    public static class Builder {
        public boolean allowContentAccess = true;
        public boolean allowFileAccess = true;
        public boolean allowFileAccessFromFileURLs = false;
        public boolean allowUniversalAccessFromFileURLs = false;
        public boolean appCacheEnabled = false;
        public String appCachePath = "";
        public boolean blockNetworkImage = true;
        public boolean builtInZoomControls = false;
        public int cacheMode = WebSettings.LOAD_DEFAULT;
        public String cursiveFontFamily = "cursive";
        public boolean databaseEnabled = false;
        public String databasePath = "";
        public int defaultFixedFontSize = 16;
        public int defaultFontSize = 16;
        public String defaultTextEncodingName = "UTF-8";
        public boolean displayZoomControls = true;
        public boolean domStorageEnabled = false;
        public String fantasyFontFamily = "fantasy";
        public String fixedFontFamily = "monospace";
        public String geolocationDatabasePath = "";
        public boolean geolocationEnabled = true;
        public boolean javaScriptCanOpenWindowsAutomatically = false;
        public boolean javaScriptEnabled = false;
        public WebSettings.LayoutAlgorithm layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
        public boolean loadWithOverviewMode = false;
        public boolean loadsImagesAutomatically = true;
        public boolean mediaPlaybackRequiresUserGesture = true;
        public int minimumFontSize = 8;
        public int minimumLogicalFontSize = 8;
        public int mixedContentMode = android.webkit.WebSettings.MIXED_CONTENT_NEVER_ALLOW;
        public boolean needInitialFocus = true;
        public boolean offscreenPreRaster = false;
        public String sansSerifFontFamily = "sans-serif";
        public boolean saveFormData = true;
        public String serifFontFamily = "sans-serif";
        public String standardFontFamily = "sans-seri";
        public boolean supportMultipleWindows = false;
        public boolean supportZoom = true;
        public int textZoom = 100;
        public boolean useWideViewPort = true;
        public String userAgentString = "";


        public void applyConfig(BaseWebViewConfig config) {
            config.allowContentAccess = allowContentAccess;
            config.allowContentAccess = allowContentAccess;
            config.allowFileAccess = allowFileAccess;
            config.allowFileAccessFromFileURLs = allowFileAccessFromFileURLs;
            config.allowUniversalAccessFromFileURLs = allowUniversalAccessFromFileURLs;
            config.appCacheEnabled = appCacheEnabled;
            config.appCachePath = appCachePath;
            config.blockNetworkImage = blockNetworkImage;
            config.builtInZoomControls = builtInZoomControls;
            config.cacheMode = cacheMode;
            config.cursiveFontFamily = cursiveFontFamily;
            config.databaseEnabled = databaseEnabled;
            config.defaultFixedFontSize = defaultFixedFontSize;
            config.defaultFontSize = defaultFontSize;
            config.defaultTextEncodingName = defaultTextEncodingName;
            config.displayZoomControls = displayZoomControls;
            config.domStorageEnabled = domStorageEnabled;
            config.fantasyFontFamily = fantasyFontFamily;
            config.fixedFontFamily = fixedFontFamily;
            config.geolocationDatabasePath = geolocationDatabasePath;
            config.geolocationEnabled = geolocationEnabled;
            config.javaScriptCanOpenWindowsAutomatically = javaScriptCanOpenWindowsAutomatically;
            config.javaScriptEnabled = javaScriptEnabled;
            config.layoutAlgorithm = layoutAlgorithm;
            config.loadWithOverviewMode = loadWithOverviewMode;
            config.loadsImagesAutomatically = loadsImagesAutomatically;
            config.mediaPlaybackRequiresUserGesture = mediaPlaybackRequiresUserGesture;
            config.minimumFontSize = minimumFontSize;
            config.minimumLogicalFontSize = minimumLogicalFontSize;
            config.mixedContentMode = mixedContentMode;
            config.needInitialFocus = needInitialFocus;
            config.offscreenPreRaster = offscreenPreRaster;
            config.sansSerifFontFamily = sansSerifFontFamily;
            config.saveFormData = saveFormData;
            config.serifFontFamily = serifFontFamily;
            config.standardFontFamily = standardFontFamily;
            config.supportMultipleWindows = supportMultipleWindows;
            config.supportZoom = supportZoom;
            config.textZoom = textZoom;
            config.useWideViewPort = useWideViewPort;
            config.userAgentString = userAgentString;
        }

        public BaseWebViewConfig build() {
            BaseWebViewConfig config = new BaseWebViewConfig();
            applyConfig(config);
            return config;
        }

        public Builder setAllowContentAccess(boolean allowContentAccess) {
            this.allowContentAccess = allowContentAccess;
            return this;
        }

        public Builder setAllowFileAccess(boolean allowFileAccess) {
            this.allowFileAccess = allowFileAccess;
            return this;
        }

        public Builder setAllowFileAccessFromFileURLs(boolean allowFileAccessFromFileURLs) {
            this.allowFileAccessFromFileURLs = allowFileAccessFromFileURLs;
            return this;
        }

        public Builder setAllowUniversalAccessFromFileURLs(boolean allowUniversalAccessFromFileURLs) {
            this.allowUniversalAccessFromFileURLs = allowUniversalAccessFromFileURLs;
            return this;
        }

        public Builder setAppCacheEnabled(boolean appCacheEnabled) {
            this.appCacheEnabled = appCacheEnabled;
            return this;
        }

        public Builder setAppCachePath(String appCachePath) {
            this.appCachePath = appCachePath;
            return this;
        }
    }

}
